﻿using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Grpc.Net.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Zhy.gRPCDemo.DefaultServer;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static Zhy.gRPCDemo.DefaultServer.AdvancedGreeter;
using static Zhy.gRPCDemo.DefaultServer.Greeter;

namespace Zhy.gRPC.MyClient
{
    /// <summary>
    /// 用于发起gRPC请求
    /// </summary>
    public static class gRPCRequest
    {
        public static async Task TestHello()
        {
            using (var channel = GrpcChannel.ForAddress("http://localhost:5186"))
            {
                GreeterClient client = new GreeterClient(channel);

                HelloReply helloReply = client.SayHello(new HelloRequest()
                {
                    Name = "gRPC测试-同步版本",
                });

                HelloReply helloReply1 = await client.SayHelloAsync(new HelloRequest()
                {
                    Name = "gRPC测试-异步版本",
                });

                Console.WriteLine($"服务返回的消息：{helloReply1.Message}");
            }
        }

        public static async Task TestgRPCService()
        {
            using (var channel = GrpcChannel.ForAddress("http://localhost:5186")) // 实例化连接对象
            {
                AdvancedGreeterClient client = new AdvancedGreeterClient(channel);


                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************单次调用*************************");
                Console.WriteLine("**************************************************");
                {
                    HelloReplyMath helloReplyMath = client.SayHello(new HelloRequestMath()
                    {
                        Id = 123,
                        Name = "天蓝"
                    });
                    Console.WriteLine($"Greeter 服务返回的消息:{helloReplyMath.Message}");


                    HelloReplyMath helloReplyMath1 = await client.SayHelloAsync(new HelloRequestMath()
                    {
                        Id = 123,
                        Name = "天蓝"
                    });
                    Console.WriteLine($"Greeter 服务返回的消息:{helloReplyMath1.Message}");
                }

                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************空参数*************************");
                Console.WriteLine("**************************************************");
                {
                    var countResult = await client.CountAsync(new Empty());
                    Console.WriteLine($"随机一下 {countResult.Count}");
                    var rand = new Random(DateTime.Now.Millisecond);
                }


                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************客户端流*************************");
                Console.WriteLine("**************************************************");
                {

                    var bathCat = client.SelfIncreaseClient();

                    for (int i = 0; i < 10; i++)
                    {
                        await bathCat.RequestStream.WriteAsync(new BathTheCatReq() { Id = new Random().Next(0, 20) }); // 客户端写入多个结果
                        await Task.Delay(600);
                        Console.WriteLine($"This is {i} Request {Thread.CurrentThread.ManagedThreadId}");
                    }

                    Console.WriteLine("**********************************");
                    //发送完毕
                    await bathCat.RequestStream.CompleteAsync(); // 告诉服务端多个结果已经写完了

                    Console.WriteLine("客户端已发送完10个id");
                    Console.WriteLine("接收结果：");


                    foreach (var item in bathCat.ResponseAsync.Result.Number)
                    {
                        Console.WriteLine($"This is {item} Result");
                    }
                    Console.WriteLine("**********************************");

                }


                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************服务端流*************************");
                Console.WriteLine("**************************************************");
                {
                    //准备的参数
                    IntArrayModel intArrayModel = new IntArrayModel();
                    for (int i = 0; i < 15; i++)
                    {
                        intArrayModel.Number.Add(i);//Number不能直接赋值，
                    }


                    var bathCat = client.SelfIncreaseServer(intArrayModel);


                    var bathCatRespTask = Task.Run(async () =>
                    {
                        await foreach (var resp in bathCat.ResponseStream.ReadAllAsync())
                        {
                            Console.WriteLine(resp.Message);
                            Console.WriteLine($"This is  Response {Thread.CurrentThread.ManagedThreadId}");
                            Console.WriteLine("**********************************");
                        }
                    });
                    Console.WriteLine("客户端已发送完10个id");
                    //开始接收响应
                    await bathCatRespTask;

                }

                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************双向流*************************");
                Console.WriteLine("**************************************************");
                {
                    //调用双向流
                    var bathCat = client.SelfIncreaseDouble();


                    //准备读取, 获取数据
                    var bathCatRespTask = Task.Run(async () =>
                    {
                        await foreach (var resp in bathCat.ResponseStream.ReadAllAsync())
                        {
                            Console.WriteLine(resp.Message);
                            Console.WriteLine($"This is  Response {Thread.CurrentThread.ManagedThreadId}");
                            Console.WriteLine("**********************************");
                        }
                    });


                    //传入多个多服务端流
                    for (int i = 0; i < 10; i++)
                    {
                        await bathCat.RequestStream.WriteAsync(new BathTheCatReq() { Id = new Random().Next(0, 20) });
                        await Task.Delay(100);
                        Console.WriteLine($"This is {i} Request {Thread.CurrentThread.ManagedThreadId}");
                        Console.WriteLine("**********************************");
                    }

                    //发送完毕
                    await bathCat.RequestStream.CompleteAsync();
                    Console.WriteLine("客户端已发送完10个id");
                    Console.WriteLine("接收结果：");
                    //开始接收响应
                    await bathCatRespTask;
                }

                
            }
        }

        /// <summary>
        /// 上传图像
        /// </summary>
        /// <returns></returns>
        public static async Task UploadFile()
        {
            using (var channel = GrpcChannel.ForAddress("http://localhost:5186")) // 实例化连接对象
            {
                AdvancedGreeterClient client = new AdvancedGreeterClient(channel);

                Console.WriteLine("**************************************************");
                Console.WriteLine("*****************上传图像*************************");
                Console.WriteLine("**************************************************");
                {
                    // 上传图像
                    var bathCat = client.UploadFile();
                    var buff = new byte[2097152];
                    string fileName = "D:\\IOIP\\VirtualDisk\\轮毂学习目录\\10038-1770\\IMG_638475758905936509.jpg";
                    string reName = Path.GetFileName(fileName); // 获取文件名和扩展名

                    using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) // 读取图片流
                    {
                        while (true)
                        {
                            var len = fileStream.Read(buff, 0, buff.Length);
                            if (len == 0)
                            {
                                break;  // 图像读取完毕
                            }
                            await bathCat.RequestStream.WriteAsync(new UploadFileReq() // 写入图像流
                            {
                                FileChunk = Google.Protobuf.ByteString.CopyFrom(buff, 0, len), // 图像流 - 写入字节数组
                                FileName = reName // 文件名称
                            });
                        }
                    }
                    await bathCat.RequestStream.CompleteAsync(); // 告诉服务器写完了
                    var rep = await bathCat.ResponseAsync; // 异步获取返回结果
                    bathCat.Dispose(); // 资源释放
                }
            }
        }
    }
}
